﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Iesi.Collections.Generic;

namespace Studentium.Entities
{
    public enum StudentLevel
    {
        Unknown,
        Starter,
        Elementary,
        PreIntermediate,
        Intermediate,
        UpperIntermediate,
        Advanced,
        Proficiency
    }

    public class Student
    {
        private int id;
        private int businessId;
        private string firstName;
        private string patronymic;
        private string lastName;
        private DateTime birthday;
        private string phone;
        private string address;
        private string email;
        private bool finished;
        private DateTime registrationDate;
        private DateTime finishDate;
        private StudentLevel level;      
        private IList<Comment> comments = new List<Comment>();
        private IList<Payment> payments = new List<Payment>();
        private IList<ClassAttendance> classes = new List<ClassAttendance>();

        public Student()
        {            
        }

        [Browsable(false)]
        public virtual int Id
        {
            get { return id; }
            set { id = value; }
        }

        [DisplayName("Id")]
        public virtual int BusinessId
        {
            get { return businessId; }
            set { businessId = value; }
        }

        [DisplayName("First name")]
        public virtual string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }

        [Browsable(false)]
        public virtual bool IsStudent
        {
            get { return businessId != 0; }            
        }

        public virtual string Patronymic
        {
            get { return patronymic; }
            set { patronymic = value; }
        }

        [DisplayName("Last name")]
        public virtual string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }

        public virtual DateTime Birthday
        {
            get { return birthday; }
            set { birthday = value; }
        }

        public virtual string Email
        {
            get { return email; }
            set { email = value; }
        }

        public virtual StudentLevel Level
        {
            get { return level; }
            set { level = value; }
        }

        public virtual string Phone
        {
            get { return phone; }
            set { phone = value; }
        }

        public virtual string Address
        {
            get { return address; }
            set { address = value; }
        }

        public virtual bool Finished
        {
            get { return finished; }
            set { finished = value; }
        }

        public virtual DateTime RegistrationDate
        {
            get { return registrationDate; }
            set { registrationDate = value; }
        }

        public virtual DateTime FinishDate
        {
            get { return finishDate; }
            set { finishDate = value; }
        }

        [Browsable(false)]
        public virtual IList<Comment> Comments
        {
            get { return comments; }
            set { comments = value; }
        }

        // purely calculated field
        public DateTime LastActivityDate
        {
            get
            {
                DateTime lastActivityDate;
                var payment = payments.OrderByDescending(x => x.FinishDate).FirstOrDefault();
                
                if (payment != null)
                {
                    lastActivityDate = payment.FinishDate;
                }
                else
                {
                    lastActivityDate = RegistrationDate;
                }

                if (Finished && FinishDate > lastActivityDate)
                {
                    lastActivityDate = FinishDate;
                }

                return lastActivityDate;
            }
        }            

        // purely virtual field
        [Browsable(false)]
        public virtual string FullName
        {
            get
            {
                string lName = LastName;
                string fName = FirstName;
                if (lName == null || lName.Trim().Length == 0)
                    lName = "(non-defined)";
                if (fName == null || fName.Trim().Length == 0)
                    fName = "(non-defined)";
                return lName + " " + fName + "(id:" + BusinessId + ")";
            }
        }

        [Browsable(false)]
        public virtual IList<Payment> Payments
        {
            get { return payments; }
            set { payments = value; }
        }

        [Browsable(false)]
        public virtual IList<ClassAttendance> Classes
        {
            get { return classes; }
            set { classes = value; }
        }

        public virtual int Credit
        {
            get
            {
                return payments.Aggregate(0, (sum, current) => sum + current.Price - current.MoneyPaid - current.Discount);
            }
        }

        public int CalcWastedClasses()
        {
            int sum = 0;
            foreach (ClassAttendance attendance in Classes)
                if ( (attendance.Status == AttendenceStatus.Attended ||
                     attendance.Status == AttendenceStatus.Registered) 
                    && attendance.CalendarEntry.IsPaidClass())
                {
                    sum++;
                }
            return sum;
        }

        public int CalcBoughtClasses()
        {
            int sum = 0;
            foreach (Payment payment in Payments)
            {
                sum += payment.ClassesNumber;
            }
            return sum;
        }
    }
}
